package com.walter.handler;

import cn.hutool.json.JSONUtil;
import com.walter.annotation.SysLog;
import com.walter.entity.Log;
import com.walter.mapper.LogMapper;
import com.walter.util.MyCommon;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * @author ：ch
 * @date ：Created in 2021/5/25
 * @description：
 * @modified By：
 * @version: 1.0
 */
@Aspect
@Component
@Slf4j
public class SysLogAspect {
    @Autowired
    private LogMapper logMapper;//sys_log

    @Pointcut("@annotation(com.walter.annotation.SysLog)")
    public void logPointCut() {

    }

    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        //执行方法
        Object result = point.proceed();
        //执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;

        //保存日志
        saveSysLog(point, time);

        return result;
    }

    private void saveSysLog(ProceedingJoinPoint joinPoint, long time) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        SysLog syslog = method.getAnnotation(SysLog.class);
        Log logEntity = new Log();
        if(syslog != null){
            //注解上的描述
            logEntity.setOperation(syslog.value());
        }

        //请求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        logEntity.setMethod(className + "." + methodName + "()");

        //请求的参数
        Object[] args = joinPoint.getArgs();
        String params;
        try {
            if (null != args && args.length > 0) {
                //log.info("1--------{}",args[0].getClass().toString());
                //log.info("2--------{}",args[0].getClass().getDeclaredFields().toString());
                //args = null;   Transactional can not rollback todo
                if (args[0].getClass().toString().equals("class java.lang.Integer")
                        || args[0].getClass().toString().equals("class java.lang.String")) { //todo strengthen logic
                    params = args[0].toString();
                }
                else if(args[0].getClass().toString().equals("class org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile")){
                    MultipartFile file = (MultipartFile)args[0];
                    params = "file[name = " + file.getOriginalFilename() + ",size = " + file.getSize() + "B]";
                }
                else {
                    params = JSONUtil.parseObj(args[0]).toStringPretty();
                    //日志不保存登录的密码
                    if (logEntity.getMethod().equals("com.walter.controller.AuthController.login()")){
                        params = JSONUtil.parseObj(args[0]).put("password","******").toStringPretty();
                    }
                    //日志不保存修改密码信息
                    if (logEntity.getMethod().equals("com.walter.controller.UserController.updatePwd()")){
                        params = JSONUtil.parseObj(args[0])
                                .put("originalPwd","******")
                                .put("newPwd","******")
                                .put("repeatedPwd","******")
                                .toStringPretty();
                    }
                }
                logEntity.setParams(params);
            }
        }
        catch (Exception e){
            e.printStackTrace();
            log.error("occurred error when calling saveSysLog():{}",e.getMessage());
        }
        //获取request
        HttpServletRequest request = MyCommon.getHttpServletRequest();
        //设置IP地址
        logEntity.setIp(MyCommon.getRemoteIP(request));
        //用户id
        try {
//            Integer currentId = (Integer)JwtUtil.currentId();
            logEntity.setUserId(1);// todo
        }
        catch (Exception e){
            log.info("Exception:\n",e);
            log.info("anno interface do not need login");
            logEntity.setUserId(null);// 登录等
        }
        logEntity.setTime(time).setCreateDate(new Date());
        logMapper.insert(logEntity);
    }
}
